﻿#pragma once
#include "reader.h"

template<typename _T>
struct BaseOutputHandler
{
	BaseOutputHandler(_T& output) : m_Output(output), m_Key(L"") {}

	bool Null(){ return false; }
	bool Bool(bool b){ return m_Output.HandleBool(m_Key, b); }
	bool Int(int i){ return m_Output.HandleInt(m_Key, i); }
	bool Uint(unsigned u){ return m_Output.HandleInt(m_Key, u); }
	bool Int64(int64_t i){ return m_Output.HandleInt(m_Key, i); }
	bool Uint64(uint64_t u){ return m_Output.HandleInt(m_Key, u); }
	bool Double(double d){ return m_Output.HandleDouble(m_Key, d); }
	bool String(const wchar_t* str, rapidjson::SizeType length, bool){ return m_Output.HandleString(m_Key, std::wstring(str, length)); }
	bool StartObject() { return m_Output.HandleStartObj(m_Key); }
	bool Key(const wchar_t* str, rapidjson::SizeType length, bool){ m_Key = std::wstring(str, length); return true; }
	bool EndObject(rapidjson::SizeType){ return m_Output.HandleEndObj(); }
	bool StartArray() { return true; }
	bool EndArray(rapidjson::SizeType) { return true; }

	_T& m_Output;
	std::wstring m_Key;
};

template<typename _TValue, typename _TKey = std::wstring, typename _CONT = std::unordered_map<_TKey, _TValue> >
class BaseReaderHandler
{
public:
	BaseReaderHandler(_CONT* cont) : m_Container(cont) {}
	bool HandleBool(const std::wstring& key, bool b) { assert(0); return false; }
	bool HandleInt(const std::wstring& key, int i) { assert(0); return false; }
	bool HandleDouble(const std::wstring& key, double d) { assert(0); return false; }
	bool HandleString(const std::wstring& key, const std::wstring& str) { assert(0); return false; }
	virtual bool HandleStartObj(const std::wstring& key)	// 派生类需要在此处向map插入内容 得到指针
	{
		if (!key.empty())
		{
			m_list_StartObjKey.push_back(key);
		}
		return true;
	}
	virtual bool HandleEndObj()
	{
		if (!m_list_StartObjKey.empty())
		{
			m_list_StartObjKey.pop_back();
		}
		return true;
	};
	
protected:
	_CONT* m_Container;		// 保存的容器 可以为NULL
	std::list<std::wstring> m_list_StartObjKey;		// 储存HandleStartObj的键入值 HandleStartObj时push HandleEndObj时pop
	std::list<void*> m_list_OperatorPtr;	// 储存嵌套struct的指针，派生类自己push pop，自己Get !注意不能存储栈指针!
	std::unordered_map<std::wstring, std::function<void(const void*)>> m_map_OperatorFunction;		// <关键字,回调lambda函数> 派生类自己定义

	// 执行m_map_OperatorFunction的模板函数 自身带警告
	bool OperatorFunction(const std::wstring& key, const void* value)
	{
		auto it_FindFunc = m_map_OperatorFunction.find(key);
		if (m_map_OperatorFunction.end() != it_FindFunc)
		{
			// 找到了 执行回调函数
			it_FindFunc->second(value);
		}
		else
		{
			// 没找到
			CString strError;
			strError.Format(L"'%s' is not exist!", key.c_str());
			CommonFunc::ErrorMessageBox(strError);
			return false;
		}
		return true;
	}
};